﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Data;
using Windows.Data.Xml.Dom;
using Windows.Networking;
using Windows.Storage;

namespace Beyondsoft.Tuanju.DataManager.DealProviders
{
    public abstract class DealProvider
    {
        private Dictionary<City, IEnumerable<Deal>> cityDeals = new Dictionary<City, IEnumerable<Deal>>();

        protected const int FetchCount = 50;

        protected abstract string Name
        {
            get;
        }

        protected abstract string ApiAddress
        {
            get;
        }

        public async Task<IEnumerable<Deal>> GetDeals(City city)
        {
            if (!this.cityDeals.ContainsKey(city))
            {
                this.cityDeals.Add(city, await FetchDeals(city));
            }

            return this.cityDeals[city];
        }

        protected abstract Task<IEnumerable<Deal>> FetchDeals(City city);

        public async Task<IEnumerable<Deal>> GetDeals(City city, Category category)
        {
            await GetDeals(city);
            return this.cityDeals[city].TakeWhile(deal => deal.Category == category);
        }

        public async Task<IEnumerable<Deal>> GetRecommends(City city, int count)
        {
            await GetDeals(city);
            return this.cityDeals[city].Take(count);
        }

        public async Task<Deal> GetDeal(City city, string dealId)
        {
            await GetDeals(city);
            return this.cityDeals[city].FirstOrDefault(deal => deal.Gid == dealId);
        }

        public static DealProvider CreateProvider(string provider)
        {
            DealProvider dealProvider = null;

            switch (provider.ToLower())
            {
                case "dianping":
                    dealProvider = new Dianping();
                    break;
                case "lashou":
                    dealProvider = new Lashou();
                    break;
                case "meituan":
                    dealProvider = new MeiTuan();
                    break;
                default:
                    break;
            }

            return dealProvider;
        }

        protected async Task<Category> ConvertFrom(string category)
        {
            Dictionary<string, string> categories = await this.GetCategoryMap();

            if (!categories.ContainsKey(category))
            {
                return Category.其他;
            }

            string cate = categories[category];

            return (Category)Enum.Parse(typeof(Category), cate);
        }

        private async Task<Dictionary<string, string>> GetCategoryMap()
        {
            const string pattern = "/providers/provider[@name='{0}']/categories/category";

            var path = string.Format(pattern, this.Name);

            StorageFolder storageFolder = await Package.Current.InstalledLocation.GetFolderAsync("Beyondsoft.Tuanju.DataManager");
            StorageFolder dataFolder = await storageFolder.GetFolderAsync("Configuration");

            StorageFile file = await dataFolder.GetFileAsync("Providers.xml");

            XmlDocument xdoc = await XmlDocument.LoadFromFileAsync(file);

            XmlNodeList nodes = xdoc.SelectNodes(path);

            Dictionary<string, string> result = new Dictionary<string, string>();

            foreach (var node in nodes)
            {
                result.Add(node.Attributes[0].InnerText, node.Attributes[1].InnerText);
            }

            return result;
        }

        public async Task<bool> IsAvailable()
        {
            System.Net.Http.HttpClient httpclient = new System.Net.Http.HttpClient();

            try
            {
                await httpclient.GetStringAsync(this.ApiAddress);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
